package com.orangelife.service.paybill.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.orangelife.common.MybaitsGenericDaoSubLogic;
import com.orangelife.exception.AppBizException;
import com.orangelife.framework.toolkit.random.RandomUtil;
import com.orangelife.other.OtherService;
import com.orangelife.service.PropFeeType.IPropFeeTypeService;
import com.orangelife.service.bill.IComputeBillService;
import com.orangelife.service.contact.IContactService;
import com.orangelife.service.feeDetail.IFeeDetailService;
import com.orangelife.service.feeDetail.modal.PropFeeDetailDto;
import com.orangelife.service.feelog.IFeeLogService;
import com.orangelife.service.feelog.modal.PropFeeLogDto;
import com.orangelife.service.paybill.IPayBillService;
import com.orangelife.service.paybill.modal.PayInfo;
import com.orangelife.service.paybill.modal.Paybill;
import com.orangelife.service.paybill.modal.PropFeePaybillDto;
import com.orangelife.service.propApp.IPropFeeMemberApartmentService;
import com.orangelife.service.propApp.model.PropFeeMemberApartment;
import com.orangelife.service.propFeeAccount.IPropFeeAccountService;
import com.orangelife.service.propFeeAccount.model.AmountHandleDto;
import com.orangelife.service.propFeeAccount.model.PropFeeAccountDto;
import com.orangelife.service.propFeeComputeRule.IPropFeeComputeRuleService;
import com.orangelife.service.propFeeOffsetInfo.IPropFeeOffsetInfoService;
import com.orangelife.service.propFeeOffsetInfo.model.PropFeeOffsetInfoDto;
import com.orangelife.service.propFeePaybillItem.IPropFeePaybillItemService;
import com.orangelife.service.propFeePaybillItem.model.PropFeePaybillItemDto;
import com.orangelife.service.property.model.UserBean;
import com.orangelife.service.propinfo.IPropInfoService;
import com.orangelife.setting.constant.TypeConst;
import com.orangelife.utils.DateUtil;
import com.orangelife.utils.IdUtil;
import com.orangelife.utils.ProConfig;
import com.orangelife.utils.PropertyUtils;
import com.orangelife.utils.StringUtils;
import com.orangelife.webservice.service.paybill.entity.BillInfo;
import com.orangelife.webservice.service.paybill.entity.PayBillDto;
import com.orangelife.webservice.service.property.entity.PropComputeBean;

@Service("payBillService")
public class PayBillService extends MybaitsGenericDaoSubLogic implements
		IPayBillService {
	@Resource(name = "propFeeTypeService")
	private IPropFeeTypeService propFeeTypeService;
	@Resource(name = "feeLogService")
	private IFeeLogService feeLogService;
	@Resource(name = "propFeeMemberApartmentService")
	private IPropFeeMemberApartmentService propFeeMemberApartmentService;
	@Resource(name = "propFeeAccountService")
	private IPropFeeAccountService propFeeAccountService;
	@Resource(name = "contactService")
	private IContactService contactService;
	@Resource(name = "computeBillService")
	private IComputeBillService computeBillService;
	@Resource(name = "propFeeComputeRuleService")
	private IPropFeeComputeRuleService propFeeComputeRuleService;

	@Resource(name = "feeDetailService")
	private IFeeDetailService feeDetailService;
	@Resource(name = "propFeePaybillItemService")
	private IPropFeePaybillItemService propFeePaybillItemService;
	@Resource(name = "propFeeOffsetInfoService")
	private IPropFeeOffsetInfoService propFeeOffsetInfoService;
	@Resource(name = "propInfoService")
	private IPropInfoService propInfoService;
	
	@Override
	public int updatePayBill(Paybill paybill) throws AppBizException {
		// TODO Auto-generated method stub

		return this.getSqlSession().update(
				"PropFeePaybillMapper.updateByPrimaryKeySelective", paybill);

	}

	@Override
	public int updatePayBill2(Paybill paybill) throws AppBizException {
		// TODO Auto-generated method stub

		return this.getSqlSession().update(
				"PropFeePaybillMapper.updatepaybill", paybill);

	}

	@Override
	public int addPayBill(Paybill paybill) throws AppBizException {

		if (paybill.getPaybillID() == null) {

			paybill.setPaybillID(IdUtil.getuuId());

		}
		// TODO Auto-generated method stub
		return this.getSqlSession().insert(
				"PropFeePaybillMapper.insertSelective", paybill);
	}

	@Override
	public Paybill getPayBillDetail(String paybillID) throws AppBizException {

		// TODO Auto-generated method stub
		return this.getSqlSession().selectOne(
				"PropFeePaybillMapper.selectByPrimaryKey", paybillID);
	}

	@Override
	public boolean checkFeeDetailIsPay(String apartmentID, List<String> feeDetailIDs)
			throws AppBizException {

		Map<String, Object> param = new HashMap<String, Object>();

		param.put("feeDetailIDs", feeDetailIDs);
		param.put("apartmentID", apartmentID);
		Map<String, Object> l = this.getSqlSession().selectOne(
				"PropFeePaybillMapper.checkFeeDetailIsPay", param);

		if (l == null) {

			return true;
		}
		String n = StringUtils.toString(l.get("cn"), "0");
		int len = Integer.parseInt(n);
		if (feeDetailIDs.size() != len) {

			return true;

		}
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public List<Map<String, Object>> getFeeDetailsByIDs(String apartmentID,
			List<String> feeDetailIDs) throws AppBizException {
		Map<String, Object> param = new HashMap<String, Object>();

		param.put("feeDetailIDs", feeDetailIDs);
		param.put("apartmentID", apartmentID);
		return this.getSqlSession().selectList(
				"PropFeePaybillMapper.getFeeDetailsByIDs", param);
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public synchronized Map<String, Object> crePayBill(
			PropComputeBean propComputeBean) throws AppBizException {
		Map<String, Object> res = new HashMap<String, Object>();
		res.put("errCode", "0");
		List<Map<String, Object>> details = this.getFeeDetailsByIDs(
				propComputeBean.getApartmentID(),
				propComputeBean.getFeeDetailIDs());

		BigDecimal payMoney = new BigDecimal("0.00");
		// 缴费期间
		String maxdate = null;
		String mindate = null;

		String paybillID = IdUtil.getuuId();
		if (details != null
				&& details.size() == propComputeBean.getFeeDetailIDs().size()) {
			// 计算缴费金额
			for (Map<String, Object> detail : details) {
				if (mindate == null) {
					mindate = StringUtils.toString(detail.get("fee_date"));

				} else {
					if (mindate.compareTo(StringUtils.toString(detail
							.get("fee_date"))) > 0) {

						mindate = StringUtils.toString(detail.get("fee_date"));
					}

				}
				if (maxdate == null) {
					maxdate = StringUtils.toString(detail.get("fee_date"));

				} else {

					if (maxdate.compareTo(StringUtils.toString(detail
							.get("fee_date"))) < 0) {

						maxdate = StringUtils.toString(detail.get("fee_date"));
					}

				}

				payMoney = payMoney.add(new BigDecimal(StringUtils
						.toString(detail.get("amount"))));

			}
			Paybill paybill = new Paybill();
			Date now = new Date();
			paybill.setApartmentID(propComputeBean.getApartmentID());
			paybill.setPaybillID(paybillID);
			paybill.setPayMoney(payMoney.toString());
			paybill.setTscreate(now);
			paybill.setTsedit(now);
			paybill.setStatus("0");
			paybill.setMemID(propComputeBean.getMemID());

			// 设置账单类型
			paybill.setType("1");
			paybill.setItemStat("1");
			paybill.setPayeeID("");
			String monthrange = "";
			if (mindate.equals(maxdate)) {

				monthrange = mindate;

			} else {

				monthrange = mindate + "至" + maxdate;

			}
			paybill.setMonthrange(monthrange);
			String paybillexpiretime = ProConfig
					.getProValues("paybillexpiretime");

			int etime = Integer.parseInt(paybillexpiretime);
			// 设置有效时间
			paybill.setExpireTime(DateUtil.addMinute(now, etime));

			// 插入缴费账单
			this.addPayBill(paybill);
			// 插入缴费账单细项

			//

			Map<String, Object> zdxxmap = new HashMap<String, Object>();
			zdxxmap.put("feeDetailIDlist", propComputeBean.getFeeDetailIDs());
			zdxxmap.put("paybill_id", paybill.getPaybillID());
			this.getSqlSession().insert(
					"CollectionItemMapper.insertpropfeepaydetail", zdxxmap);

			res.put("payBillID", paybillID);
			res.put("payMoney", paybill.getPayMoney());
//
//			PropFeeLogDto log = new PropFeeLogDto();
//
//			log.setLogID(IdUtil.getuuId());
//			log.setType("1");
//			log.setContentValue(paybill.getPaybillID());
//
//			log.setContent("生成缴费账单");
//			log.setOperation("1");
//			feeLogService.addLog(log);

		} else {
			res.put("errCode", "98");
			res.put("errInfo", "有他人缴纳了该账单中的费用，请下拉页面重新加载");
			return res;
		}
		// TODO Auto-generated method stub
		return res;
	}

	@Override
	public List<String> getPayBillDetailIDs(String payBillID)
			throws AppBizException {

		Map<String, Object> param = new HashMap<String, Object>();
		param.put("payBillID", payBillID);

		// TODO Auto-generated method stub
		return this.getSqlSession().selectList(
				"PropFeePaybillMapper.getPayBillDetailIDs", param);
	}

	@Override
	public int dealPayBill(PayInfo payInfo) throws AppBizException {

		// 获取账单信息
		Paybill paybill = this.getPayBillDetail(payInfo.getOrderID());

		PropFeeLogDto log = new PropFeeLogDto();

		log.setLogID(IdUtil.getuuId());

		log.setType("1");
		log.setContentValue(payInfo.getOrderID());

		// 验证是否已被支付

		if ("0".equals(paybill.getStatus()) || "1".equals(paybill.getStatus())) {

			// 验证订单是否过期

			if (paybill.getExpireTime() != null) {

				Date now = new Date();
				// 过期
				if (now.getTime() > paybill.getExpireTime().getTime()) {

					paybill.setStatus("4");
					paybill.setException("账单已过期");
					paybill.setExceptionstatus("2");
					this.updatePayBill(paybill);
					// 异常日志
					log.setContent("缴费失败,原因：账单已过期，缴费渠道:"
							+ payInfo.getPayChannel().get(payInfo.getPayName())
							+ ";交易号:" + payInfo.getTradeno());
					log.setOperation("5");
					log.setContentValue(paybill.getPaybillID());
					feeLogService.addLog(log);
					return 1;
					// throw new AppBizException(1200001, "该账单已过期");
				}
			}

			// 验证缴费细项是否已被支付；
			List<String> detailIDs = this.getPayBillDetailIDs(payInfo
					.getOrderID());

			boolean ispay = this.checkFeeDetailIsPay(paybill.getApartmentID(),
					detailIDs);

			if (ispay) {

				paybill.setStatus("5");
				paybill.setExceptionstatus("2");
				paybill.setException("该账单缴费信息已变更");
				this.updatePayBill(paybill);
				// 日志 加入支付信息；
				log.setContent("缴费失败,原因：该账单缴费信息已变更，缴费渠道:"
						+ payInfo.getPayChannel().get(payInfo.getPayName())
						+ ";交易号:" + payInfo.getTradeno());
				log.setOperation("5");
				log.setContentValue(paybill.getPaybillID());
				feeLogService.addLog(log);
				return 2;
				// throw new AppBizException(1200001, "该账单缴费信息已变更");

			}

			else {
				// $scope.payChannel=["","支付宝","2积分","余额支付","连连支付","微信支付","服务窗口支付宝"];

				paybill.setPayType("3");

				paybill.setPayChannel(payInfo.getPayName());

				paybill.setStatus("2");
				paybill.setTradeno(payInfo.getTradeno());
				Date payTime = new Date();
				paybill.setPayTime(payTime);
				// paybill.setPayTime(DateUtil.fomartDateToString(new Date(),
				// "yyyy-MM-dd HH:mm:ss"));
				this.updatePayBill(paybill);

				// 更新缴费细项

				log.setContent("缴费成功，缴费渠道:"
						+ payInfo.getPayChannel().get(payInfo.getPayName())
						+ ";交易号:" + payInfo.getTradeno());
				log.setOperation("4");
				log.setContentValue(paybill.getPaybillID());
				feeLogService.addLog(log);
				this.setFeeDetailsPay(paybill.getApartmentID(),
						detailIDs
								);

				List<PropFeeMemberApartment> list = new ArrayList<PropFeeMemberApartment>();
				list = propFeeMemberApartmentService.selectList(
						paybill.getApartmentID(), paybill.getCommID(),
						paybill.getMemID());
				if (list.size() == 0) {
					PropFeeMemberApartment propFeeMemberApartment = new PropFeeMemberApartment();
					propFeeMemberApartment.setId(RandomUtil.getuuId());
					propFeeMemberApartment.setApartmentId(paybill
							.getApartmentID());
					propFeeMemberApartment.setCommId(paybill.getCommID());
					propFeeMemberApartment.setItemStat("1");
					propFeeMemberApartment.setMemberId(paybill.getMemID());
					propFeeMemberApartment.setTscreate(new Date());
					propFeeMemberApartment.setTsedit(new Date());
					list.add(propFeeMemberApartment);

					propFeeMemberApartmentService.insertSelectiveByList(list);

				}

			}

		} else if ("2".equals(paybill.getStatus())) {

			if (StringUtils.isBlank(paybill.getTradeno())) {

				paybill.setExceptionstatus("2");
				paybill.setException("重复缴费");
				this.updatePayBill(paybill);

				log.setContent("缴费失败，原因:重复缴费,缴费渠道:"
						+ payInfo.getPayChannel().get(payInfo.getPayName())
						+ ";交易号:" + payInfo.getTradeno());
				log.setOperation("5");
				log.setContentValue(paybill.getPaybillID());
				feeLogService.addLog(log);

				return 3;
				// throw new AppBizException(1200001, "重复缴费");

			}
			if (!paybill.getTradeno().equals(payInfo.getTradeno())) {
				paybill.setExceptionstatus("2");

				paybill.setException("重复缴费");
				this.updatePayBill(paybill);

				log.setContent("缴费失败，原因:重复缴费,缴费渠道:"
						+ payInfo.getPayChannel().get(payInfo.getPayName())
						+ ";交易号:" + payInfo.getTradeno());
				log.setOperation("5");
				log.setContentValue(paybill.getPaybillID());
				feeLogService.addLog(log);

				return 3;

				// throw new AppBizException(1200001, "重复缴费");

			} else if ("4".equals(paybill.getStatus())) {

				paybill.setException("账单已过期");
				paybill.setExceptionstatus("2");
				this.updatePayBill(paybill);
				// 异常日志
				log.setContent("缴费失败,原因：账单已过期，缴费渠道:"
						+ payInfo.getPayChannel().get(payInfo.getPayName())
						+ ";交易号:" + payInfo.getTradeno());
				log.setOperation("5");
				log.setContentValue(paybill.getPaybillID());
				feeLogService.addLog(log);
				return 1;

			} else if ("5".equals(paybill.getStatus())) {

				paybill.setException("账单已过期");
				paybill.setExceptionstatus("2");
				this.updatePayBill(paybill);
				// 异常日志
				log.setContent("缴费失败,原因：账单已失效，缴费渠道:"
						+ payInfo.getPayChannel().get(payInfo.getPayName())
						+ ";交易号:" + payInfo.getTradeno());
				log.setOperation("5");
				log.setContentValue(paybill.getPaybillID());
				feeLogService.addLog(log);
				return 5;
			} else if ("3".equals(paybill.getStatus())) {

				paybill.setException("账单异常");
				paybill.setExceptionstatus("2");
				this.updatePayBill(paybill);
				// 异常日志
				log.setContent("缴费失败,原因：账单异常，缴费渠道:"
						+ payInfo.getPayChannel().get(payInfo.getPayName())
						+ ";交易号:" + payInfo.getTradeno());
				log.setOperation("5");
				log.setContentValue(paybill.getPaybillID());
				feeLogService.addLog(log);
				return 4;
			} else {
				paybill.setException("账单异常");
				paybill.setExceptionstatus("2");
				this.updatePayBill(paybill);
				// 异常日志
				log.setContent("缴费失败,原因：未知，缴费渠道:"
						+ payInfo.getPayChannel().get(payInfo.getPayName())
						+ ";交易号:" + payInfo.getTradeno());
				log.setOperation("5");
				log.setContentValue(paybill.getPaybillID());
				feeLogService.addLog(log);
				return 6;

			}

		}

		return 0;
	}

	
	private PropFeeAccountDto getAmount (String apartmentID)  throws AppBizException{
		
		
		
		PropFeeAccountDto propFeeAccount = propFeeAccountService.getAccountByApartID(apartmentID);
		
		return propFeeAccount;
		
	}
	
	//处理缴费金额生成账户记录 和缴费账单记录
	private int dealMoney(Paybill paybill,PayBillDto payBillDto) throws AppBizException{
		int n=0;
		
		// 设置实际需付款金额
		if (StringUtils.isBlank(payBillDto.getRealMoney())) {

			paybill.setRealMoney(paybill.getPayMoney());

		} else {

			paybill.setRealMoney(payBillDto.getRealMoney());

		}
		
		paybill.setRealPay(payBillDto.getRealPay());
		List<PropFeePaybillItemDto> pp=new ArrayList<PropFeePaybillItemDto>();
		 
		  //欠费金额	
	      BigDecimal oweMoney=BigDecimal.ZERO;
		  //预缴金额 
          BigDecimal subMoney=BigDecimal.ZERO;
          //实际应付金额 
          BigDecimal realMoney=new BigDecimal(payBillDto.getRealMoney());
          //实收金额
           BigDecimal realPay=new BigDecimal(payBillDto.getRealPay());		           
           //充值金额
           BigDecimal chargeMoney=BigDecimal.ZERO;
           //还款后金额
           BigDecimal restMoney=BigDecimal.ZERO;
           //还款后金额
           BigDecimal restMoney1=BigDecimal.ZERO;
		// 欠费金额
		if (!StringUtils.isBlank(payBillDto.getOweMoney())) {

			oweMoney=new BigDecimal(payBillDto.getOweMoney());

		}
		paybill.setSubMoney("0");
		//预缴金额
		if (!StringUtils.isBlank(payBillDto.getSubMoney())){
			subMoney=new BigDecimal(payBillDto.getSubMoney());
			paybill.setSubMoney(subMoney.toString());
	
			
		}
		
		
		 //付应缴金额后剩余的钱
		 restMoney=realPay.subtract(realMoney.add(oweMoney).subtract(subMoney));
		//归还欠款后的钱
		 restMoney1=realPay.subtract(oweMoney);
		 if(restMoney1.compareTo(BigDecimal.ZERO)>0){
			 
			 PropFeePaybillItemDto p=new PropFeePaybillItemDto();
				p.setPaybillID(paybill.getPaybillID());
			    p.setItemID(IdUtil.getuuId());
			    p.setItemName("支付物业费");
			    p.setMoney(restMoney.compareTo(BigDecimal.ZERO)>=0?restMoney1.subtract(restMoney):restMoney1);
			    p.setItemType(1);
			    p.setType(1);
			    p.setItemStat("1");
			    pp.add(p);
			 
		 }
		 
		 
		 
		 
		 //付应缴钱
		 
		 PropFeeAccountDto propFeeAccount=null;
		 BigDecimal preMoney =null;
	if(oweMoney.compareTo(BigDecimal.ZERO)>0||subMoney.compareTo(BigDecimal.ZERO)>0||restMoney.compareTo(BigDecimal.ZERO)!=0){
		
		
		propFeeAccount=this.getAmount(paybill.getApartmentID());
		
		preMoney=propFeeAccount.getMoney();
		
	}
		
		
	  if(subMoney.compareTo(BigDecimal.ZERO)>0){
		//余额付款	
		//检测预付款是否充足				
	   if (subMoney.compareTo(preMoney) > 0) {

			return -1;
	 	}
		AmountHandleDto amountHandle=new AmountHandleDto();
		amountHandle.setAccountID(propFeeAccount.getAccountID());
		amountHandle.setOperation("2");
		amountHandle.setLinkID(paybill.getPaybillID());
		amountHandle.setMoney(subMoney);
		amountHandle.setCreateuser(payBillDto.getCreateuser());
		amountHandle.setCreateuserID(payBillDto.getCreateuserID());
		amountHandle.setTotalMoney(propFeeAccount.getMoney());
		amountHandle.setRemark("余额支付物业费 "+subMoney+"元");
		amountHandle.setLogType(3);				
		propFeeAccountService.handleAccount(amountHandle);	
		amountHandle.setApartmentID(paybill.getApartmentID());
		amountHandle.setTotalMoney(propFeeAccount.getMoney());
		propFeeAccount.setMoney(propFeeAccount.getMoney().subtract(subMoney));
		PropFeePaybillItemDto p=new PropFeePaybillItemDto();
		p.setPaybillID(paybill.getPaybillID());
	    p.setItemID(IdUtil.getuuId());
	    p.setLinkID(propFeeAccount.getAccountID());
	    p.setMoney(subMoney);
	    p.setItemName("余额支付物业费");
	    p.setItemType(2);
	    p.setType(2);
	    p.setItemStat("1");
	    pp.add(p);
		
     	}
							
		if(oweMoney.compareTo(BigDecimal.ZERO)>0){
			//还款					
			AmountHandleDto amountHandle=new AmountHandleDto();
			amountHandle.setOperation("1");
			amountHandle.setLogType(4);
			amountHandle.setAccountID(propFeeAccount.getAccountID());
			amountHandle.setLinkID(paybill.getPaybillID());
			amountHandle.setApartmentID(paybill.getApartmentID());
			amountHandle.setMoney(oweMoney);
			amountHandle.setCreateuser(payBillDto.getCreateuser());
			amountHandle.setCreateuserID(payBillDto.getCreateuserID());
			amountHandle.setTotalMoney(propFeeAccount.getMoney());
			propFeeAccount.setMoney(propFeeAccount.getMoney().add(oweMoney));
			amountHandle.setRemark("还物业费欠款 "+oweMoney+"元");
			propFeeAccountService.handleAccount(amountHandle);						
			PropFeePaybillItemDto p=new PropFeePaybillItemDto();
			p.setPaybillID(paybill.getPaybillID());
		    p.setItemID(IdUtil.getuuId());
		    p.setItemName("还账户欠款");
		    p.setItemType(3);
		    p.setType(1);
		    p.setLinkID(propFeeAccount.getAccountID());
		    p.setMoney(oweMoney);
		    p.setItemStat("1");
		    pp.add(p);
		}
						
		if(restMoney.compareTo(BigDecimal.ZERO)>0){
			
			//充值				
			AmountHandleDto amountHandle=new AmountHandleDto();
			amountHandle.setOperation("1");
			amountHandle.setAccountID(propFeeAccount.getAccountID());
			amountHandle.setMoney(restMoney);
			amountHandle.setCreateuser(payBillDto.getCreateuser());
			amountHandle.setCreateuserID(payBillDto.getCreateuserID());
			amountHandle.setLogType(5);
			amountHandle.setLinkID(paybill.getPaybillID());
			amountHandle.setApartmentID(paybill.getApartmentID());
			amountHandle.setRemark("物业缴费缴纳余额转存 "+restMoney+"元");
			amountHandle.setTotalMoney(propFeeAccount.getMoney());
			propFeeAccountService.handleAccount(amountHandle);	
			propFeeAccount.setMoney(propFeeAccount.getMoney().add(restMoney));
			PropFeePaybillItemDto p=new PropFeePaybillItemDto();
			p.setPaybillID(paybill.getPaybillID());
		    p.setItemID(IdUtil.getuuId());
		    p.setItemName("余额转存");
		    p.setItemType(5);
		    p.setType(1);
		    p.setMoney(restMoney.abs());
		    p.setLinkID(propFeeAccount.getAccountID());
		    p.setItemStat("1");
		    pp.add(p);
		}					
		if(restMoney.compareTo(BigDecimal.ZERO)<0){
			//借款					
			AmountHandleDto amountHandle=new AmountHandleDto();
			amountHandle.setOperation("2");
			amountHandle.setAccountID(propFeeAccount.getAccountID());
			amountHandle.setApartmentID(paybill.getApartmentID());
			amountHandle.setMoney(restMoney.abs());
			amountHandle.setCreateuser(payBillDto.getCreateuser());
			amountHandle.setCreateuserID(payBillDto.getCreateuserID());
			amountHandle.setLogType(6);
			amountHandle.setLinkID(paybill.getPaybillID());
			amountHandle.setRemark("借款支付物业缴费 "+restMoney+"元");
			amountHandle.setTotalMoney(propFeeAccount.getMoney());
			propFeeAccountService.handleAccount(amountHandle);	
			propFeeAccount.setMoney(propFeeAccount.getMoney().subtract(restMoney.abs()));
			PropFeePaybillItemDto p=new PropFeePaybillItemDto();
			p.setPaybillID(paybill.getPaybillID());
		    p.setItemID(IdUtil.getuuId());
		    p.setItemName("借款支付物业缴费");
		    p.setMoney(restMoney.abs());
		    p.setLinkID(propFeeAccount.getAccountID());
		    p.setItemType(4);
		    p.setType(2);
		    p.setItemStat("1");
		    pp.add(p);
		
		}
		
		if(propFeeAccount!=null){
			PropFeePaybillItemDto p=new PropFeePaybillItemDto();
			p.setPaybillID(paybill.getPaybillID());
		    p.setItemID(IdUtil.getuuId());
		    p.setItemName("房屋账户余额");
		    p.setMoney(propFeeAccount.getMoney());
		    p.setLinkID(propFeeAccount.getAccountID());
		    p.setItemType(6);
		    p.setType(3);
		    p.setItemStat("1");
		    pp.add(p);
			
		}
							
	
		
		propFeePaybillItemService.addPropFeePaybillItems(pp);
		
		return n;
	}
	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public synchronized int dealPayBillOffline(PayBillDto payBillDto) throws AppBizException {

		// 获取账单信息
		Paybill paybill = this.getPayBillDetail(payBillDto.getPaybillID());

		// 验证订单是否过期

		if ("4".equals(paybill.getStatus())) {

			return 1;
		}

		if ("0".equals(paybill.getStatus()) || "1".equals(paybill.getStatus())) {
			// 验证订单是否过期
			if (paybill.getExpireTime() != null) {

				Date now = new Date();
				// 过期
				if (now.getTime() > paybill.getExpireTime().getTime()) {

					paybill.setStatus("4");

					this.updatePayBill(paybill);
					// 异常日志

					return 1;
					// throw new AppBizException(1200001, "该账单已过期");
				}
			}

			// 验证缴费细项是否已被支付；
			List<String> detailIDs = this.getPayBillDetailIDs(payBillDto
					.getPaybillID());

		List<Map<String,Object>>details = this.getFeeDetailsByIDs(paybill.getApartmentID(),
					 detailIDs);
			
			boolean ispay=false;
			
			if(details==null||details.size()!=detailIDs.size()){
				
				ispay=true;
				
			}
			
			

			if (ispay) {

				paybill.setStatus("5");
				this.updatePayBill(paybill);

				return 2;

			}

			else {

				
				int n=this.dealMoney(paybill,payBillDto);
				if(n!=0){
					
					return n;
				}
				
				
				paybill.setStatus("2");
				paybill.setPayType(payBillDto.getPayType());

				Date payTime = new Date();
				paybill.setPayTime(payTime);
				// 设置发票号
				String invoiceNumMsg = "";
				if (!StringUtils.isBlank(payBillDto.getInvoiceNum())) {
					paybill.setInvoiceNum(payBillDto.getInvoiceNum());
					paybill.setInvoiceTime(new Date());
					invoiceNumMsg = "发票单号：" + payBillDto.getInvoiceNum() + "，";

				}
				// 设置联系信息
				if (!StringUtils.isBlank(payBillDto.getPhone())
						&& !StringUtils.isBlank(payBillDto.getContactType())) {
					paybill.setPhone(payBillDto.getPhone());
					paybill.setContactType(payBillDto.getContactType());
					contactService.setContactByApartmentID(
							payBillDto.getApartmentID(),
							payBillDto.getContactType(), payBillDto.getPhone());

				}

			

				this.updatePayBill(paybill);

				// 更新缴费细项

				this.setFeeDetailsPay(paybill.getApartmentID(),
					 detailIDs);
				
				
				for (Map<String, Object> map : details) {
					PropFeeOffsetInfoDto pof = new PropFeeOffsetInfoDto();
					pof.setAmount(new BigDecimal(map.get("amount").toString()) );
					pof.setOffsetMoney(new BigDecimal(map.get("amount").toString()));
					pof.setFeeDate(map.get("fee_date").toString());
					pof.setFeeDetailID(map.get("fee_detail_id").toString());
					pof.setFeeTypeID(map.get("fee_type_id").toString());
					pof.setCommID(payBillDto.getCommID());
					pof.setStatus("2");
					pof.setApartmentID(payBillDto.getApartmentID());
					pof.setOffsetTime(paybill.getPayTime());
					pof.setOffsetType("2");
					pof.setOrderID(paybill.getPaybillID());
					propFeeOffsetInfoService.addPropFeeOffsetInfo(pof);
					
				}
				
				

				
				
				// 验证是否发短信
				if (!StringUtils.isBlank(payBillDto.getPhone())) {
//					propInfoService
					final Map<String, Object> m = new HashMap<String, Object>();

					List<String> mobileList = new ArrayList<String>();
					mobileList.add(payBillDto.getPhone());
					m.put("mobileList", mobileList);

					// String url
					// =ProConfig.getProValues("paybillQRcodeUrl")+"?commID="+commID+"&paybillID="+paybillID;
					
					try{
						
						
						String isdebug=ProConfig.getProValues("IS_DEBUG");
						
						
						if(isdebug==null||"0".equals(isdebug)){
							
							Map<String, Object> apartInfo=propInfoService.getApartmentInfo(payBillDto.getApartmentID());
							
							
							String content = "尊敬的业主，您("+StringUtils.toString(apartInfo.get("comm"), "")+StringUtils.toString(apartInfo.get("building_name"), "")+StringUtils.toString(apartInfo.get("unit_name"), "")+StringUtils.toString(apartInfo.get("apartment_num"), "")+")于"
									+ DateUtil.fomartDateToString(payTime,
											"yyyy年MM月dd HH:mm") + " 成功缴纳物业费"+ paybill.getRealPay()+"元";
							
//							："
//							+ paybill.getRealPay() + "元，缴费期间："
//							+ paybill.getMonthrange() + "，" + invoiceNumMsg
//							+ "更多缴费详情请下载橙子生活APP http://xxxx.com";
							m.put("content", content);
							m.put("type", "4");
							
							Thread t=new Thread(){
								
								
								public void run(){
									
									try {
										OtherService.sendMsg(m);
									} catch (AppBizException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}	
									
									
								}
							};
						t.start();
							
							
							
						}
						
					
						
					}catch(Exception e){
						
						
						e.printStackTrace();
					}
					

				}
			}

		} else if ("2".equals(paybill.getStatus())) {
			return 3;

		} else if ("5".equals(paybill.getStatus())) {
			return 5;

		} else if ("3".equals(paybill.getStatus())) {
			return 3;

		}

		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public List<Map<String, Object>> getFeeDetails(String commID,
			String apartmentID, String[] feeDetailIDs) throws AppBizException {

		// Map<String,Object> feeTypes=this.getFeeTypeCodeAndSql(sta, null,
		// null);

		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<String, Object> getPayBillDetailHasApInfo(String paybillID)
			throws AppBizException {
		// TODO Auto-generated method stub
		return this.getSqlSession().selectOne(
				"PropFeePaybillMapper.selectPayBillDetailHasApInfo", paybillID);
	}

	@Override
	public List<Map<String, Object>> getPayBillDetails(String PayBillID)
			throws AppBizException {

		Map<String, Object> param = new HashMap<String, Object>();
		param.put("payBillID", PayBillID);
		// TODO Auto-generated method stub
		return this.getSqlSession().selectList(
				"PropFeePaybillMapper.getPayBillDetailInfo", param);
	}

	@Override
	public int setFeeDetailsPay(String apartmentID, List<String> feeDetailIDs)
			throws AppBizException {

		Map<String, Object> param = new HashMap<String, Object>();
		param.put("apartmentID", apartmentID);
		param.put("feeDetailIDs", feeDetailIDs);
		// TODO Auto-generated method stub
		return this.getSqlSession().update(
				"PropFeePaybillMapper.updateFeeDetailsPay", param);

	}

	@Override
	public List<Map<String, Object>> getFeeDetailsByApartmentID(
			String apartmentID) throws AppBizException {

		Map<String, Object> param = new HashMap<String, Object>();
		param.put("apartmentID", apartmentID);

		return this.getSqlSession().selectList(
				"PropFeePaybillMapper.getOweFeeDetail", param);

	}

	@Override
	public List<Map<String, Object>> getPayBill(Map<String, Object> param)
			throws AppBizException {

		int pageNo = Integer.valueOf((String) param.get("pageIndex"));
		int pageSize = Integer.valueOf((String) param.get("pageSize"));
		PageHelper.startPage(pageNo, pageSize);

		return this.getSqlSession().selectList(
				"PropFeePaybillMapper.getPayBill", param);

	}

	@Override
	public int _offlineBill(PayBillDto payBillDto) throws AppBizException {
		// TODO Auto-generated method stub
		return 0;
	}

	
	private Map<String,Object> returnMap(Map<String,Object> res,String code,Object object){
		
		res.put("errCode", code);
		
		res.put("errCode", object);
		
		return res;
	}
	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public synchronized Map<String, Object> crePayBillBack(PayBillDto payBillDto)
			throws AppBizException {
		Map<String, Object> res = new HashMap<String, Object>();
		res.put("errCode", "0");
		
		 Paybill p= 	this.getPayBillDetailByOrderID(payBillDto.getOrderID());
		 
		 if(p!=null){
			 
				res.put("payBillID", p.getPaybillID());
				res.put("payMoney", p.getPayMoney()); 
			 return res;
			 
		 }
		
		List<Map<String, Object>> details = this.getFeeDetailsByIDs(
				payBillDto.getApartmentID(), payBillDto.getFeeDetailIDs());

		BigDecimal payMoney = new BigDecimal("0.00");
		// 缴费期间
		String maxdate = null;
		String mindate = null;

		String paybillID = IdUtil.getuuId();
		
		
		if (details != null
				&& details.size() == payBillDto.getFeeDetailIDs().size()) {
			// 计算缴费金额
			for (Map<String, Object> detail : details) {
				if (mindate == null) {
					mindate = StringUtils.toString(detail.get("fee_date"));

				} else {
					if (mindate.compareTo(StringUtils.toString(detail
							.get("fee_date"))) > 0) {

						mindate = StringUtils.toString(detail.get("fee_date"));
					}

				}
				if (maxdate == null) {
					maxdate = StringUtils.toString(detail.get("fee_date"));

				} else {

					if (maxdate.compareTo(StringUtils.toString(detail
							.get("fee_date"))) < 0) {

						maxdate = StringUtils.toString(detail.get("fee_date"));
					}

				}

				payMoney = payMoney.add(new BigDecimal(StringUtils
						.toString(detail.get("amount"))));

			}
			
			
			
			
			
			
			
			//对传入的金额进行校验
			
			
			if (!StringUtils.isBlank(payBillDto.getRealMoney())) {	
				if (!StringUtils.isDouble(payBillDto.getRealMoney())) {

				
					return this.returnMap(res, "98", "实际应收金额格式错误");
				}
			
			}
			if (StringUtils.isBlank(payBillDto.getRealPay())) {	
			
				return this.returnMap(res, "98", "实际应收金额格式错误");
			
			}
			
			if (!StringUtils.isDouble(payBillDto.getRealPay())) {

				return this.returnMap(res, "98", "实际应收金额格式错误");
			}
		
			
			if (!StringUtils.isBlank(payBillDto.getSubMoney())) {

				if (!StringUtils.isDouble(payBillDto.getSubMoney())) {
				
					return this.returnMap(res, "98", "预缴付款金额格式错误");
					
				}

			}
			if (!StringUtils.isBlank(payBillDto.getOweMoney())) {

				if (!StringUtils.isDouble(payBillDto.getOweMoney())) {
				
					return this.returnMap(res, "98", "欠费金额格式错误");
				
				}

			}
			
			//校验缴费项是否已缴
			
		boolean flag=	this.checkFeeDetailIsPay(payBillDto.getApartmentID(), payBillDto.getFeeDetailIDs());
			
			if(flag){
				
				return this.returnMap(res, "98", "缴费细项已发生变化");
				
			}
			//处理金额
			
			
			Paybill paybill=new Paybill();
			paybill.setPayMoney(payMoney.toString());
			paybill.setApartmentID(payBillDto.getApartmentID());
			paybill.setPaybillID(paybillID);
			
			
			int n=this.dealMoney(paybill,payBillDto);
			if(n!=0){
				
				//return n;
			}
			
			
			
			
			//生成缴费账单
		
			Date now = new Date();
			paybill.setApartmentID(payBillDto.getApartmentID());
			paybill.setPaybillID(paybillID);
			paybill.setOrderID(payBillDto.getOrderID());
			paybill.setBillType(payBillDto.getBillType());
			paybill.setPayMoney(payMoney.toString());
			paybill.setTscreate(now);
			paybill.setTsedit(now);
			paybill.setStatus("2");
			paybill.setMemID(payBillDto.getMemID());
			paybill.setTradeno(payBillDto.getTradeno());
			paybill.setCommID(payBillDto.getCommID());
			paybill.setSubMoney(StringUtils.isBlank(payBillDto.getSubMoney())?"0":payBillDto.getSubMoney());
			paybill.setRealMoney(StringUtils.isBlank(payBillDto.getRealMoney())?payBillDto.getPayMoney():payBillDto.getRealMoney());
			paybill.setRealPay(StringUtils.isBlank(payBillDto.getRealPay())?payBillDto.getRealMoney():payBillDto.getRealPay());
			paybill.setPayType(payBillDto.getPayType());
			// 设置账单类型
			paybill.setType(payBillDto.getType());
			paybill.setPayChannel(payBillDto.getPayChannel());
			paybill.setContactType(payBillDto.getContactType());
			paybill.setPhone(payBillDto.getPhone());
			paybill.setItemStat("1");
			paybill.setPayeeID("");
			paybill.setPayTime(new Date(Long.parseLong(payBillDto.getPayTime())));
			String monthrange = "";
			if (mindate.equals(maxdate)) {

				monthrange = mindate;

			} else {

				monthrange = mindate + "至" + maxdate;

			}
			paybill.setMonthrange(monthrange);


			// 插入缴费账单
			this.addPayBill(paybill);
			// 插入缴费账单细项

			//

			Map<String, Object> zdxxmap = new HashMap<String, Object>();
			zdxxmap.put("feeDetailIDlist", payBillDto.getFeeDetailIDs());
			zdxxmap.put("paybill_id", paybill.getPaybillID());
			this.getSqlSession().insert(
					"CollectionItemMapper.insertpropfeepaydetail", zdxxmap);
			
			//设置账单已缴费
			this.setFeeDetailsPay(paybill.getApartmentID(),
					payBillDto.getFeeDetailIDs());
			
			
			
			
			
			
			
			
			for (Map<String, Object> map : details) {
				PropFeeOffsetInfoDto pof = new PropFeeOffsetInfoDto();
				pof.setAmount(new BigDecimal(map.get("amount").toString()) );
				pof.setOffsetMoney(new BigDecimal(map.get("amount").toString()));
				pof.setFeeDate(map.get("fee_date").toString());
				pof.setFeeDetailID(map.get("fee_detail_id").toString());
				pof.setFeeTypeID(map.get("fee_type_id").toString());
				pof.setCommID(payBillDto.getCommID());
				pof.setApartmentID(payBillDto.getApartmentID());
				pof.setOffsetTime(paybill.getPayTime());
				pof.setOffsetType("2");
				pof.setOrderID(paybill.getPaybillID());
				propFeeOffsetInfoService.addPropFeeOffsetInfo(pof);
				
			}
			
			
			
			
			
			res.put("payBillID", paybillID);
			res.put("payMoney", paybill.getPayMoney());
//
//			PropFeeLogDto log = new PropFeeLogDto();
//
//			log.setLogID(IdUtil.getuuId());
//			log.setType("1");
//			log.setContentValue(paybill.getPaybillID());
//
//			log.setContent("生成缴费账单");
//			log.setOperation("1");
//			feeLogService.addLog(log);
			
			
			
			
			
			
			
			// 验证是否发短信
			if (!StringUtils.isBlank(payBillDto.getPhone())) {
//				propInfoService
				final Map<String, Object> m = new HashMap<String, Object>();

				List<String> mobileList = new ArrayList<String>();
				mobileList.add(payBillDto.getPhone());
				m.put("mobileList", mobileList);

				// String url
				// =ProConfig.getProValues("paybillQRcodeUrl")+"?commID="+commID+"&paybillID="+paybillID;
				
				try{
					
					
					String isdebug=ProConfig.getProValues("IS_DEBUG");
					
					
					if(isdebug==null||"0".equals(isdebug)){
						
						Map<String, Object> apartInfo=propInfoService.getApartmentInfo(payBillDto.getApartmentID());
						
						
						String content = "尊敬的业主，您("+StringUtils.toString(apartInfo.get("comm"), "")+" "+StringUtils.toString(apartInfo.get("building_name"), "")+StringUtils.toString(apartInfo.get("unit_name"), " ")+StringUtils.toString(apartInfo.get("apartment_num"), "")+")于"
								+ DateUtil.fomartDateToString(paybill.getPayTime(),
										"yyyy年MM月dd HH:mm") + " 成功缴纳物业费"+ paybill.getRealPay()+"元";
						
//						："
//						+ paybill.getRealPay() + "元，缴费期间："
//						+ paybill.getMonthrange() + "，" + invoiceNumMsg
//						+ "更多缴费详情请下载橙子生活APP http://xxxx.com";
						m.put("content", content);
						m.put("type", "4");
						
						Thread t=new Thread(){
							
							
							public void run(){
								
								try {
									OtherService.sendMsg(m);
								} catch (AppBizException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}	
								
								
							}
						};
					t.start();
						
						
					}
					
					

					
					
				}catch(Exception e){
					
					
					e.printStackTrace();
				}
				

			}
			
			
		} else {
			res.put("errCode", "98");
			res.put("errInfo", "有他人缴纳了该账单中的费用，请下拉页面重新加载");
			return res;
		}

		return res;
	}

	@Override
	public List<Map<String, Object>> findPropFeePaybillByPage(
			Map<String, Object> map, int pageNo, int pageSize)
			throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		PageHelper.startPage(pageNo, pageSize);
		List<Map<String, Object>> list = this.getSqlSession().selectList(
				"PropFeePaybillSearchMapper.findAllPropFeePaybill", map);
		return list;
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public int addPropFeePaybill(BillInfo propFeePaybill)
			throws AppBizException {

		if (StringUtils.isBlank(propFeePaybill.getFeeTypeID())) {
			throw new AppBizException(2, "费用类目");
		}
		if (StringUtils.isBlank(propFeePaybill.getCommID())) {
			throw new AppBizException(2, "小区信息");
		}
		if (StringUtils.isBlank(propFeePaybill.getApartmentID())) {
			throw new AppBizException(2, "房屋信息");
		}
		if (StringUtils.isBlank(propFeePaybill.getPayType())) {
			throw new AppBizException(2, "支付信息");
		} else {

			if (!propFeePaybill.getPayType().equals("0")
					&& !propFeePaybill.getPayType().equals("1")
					&& !propFeePaybill.getPayType().equals("2")) {
				throw new AppBizException(2, "支付信息错误");
			}
		}
		if (propFeePaybill.getPayMoney() == null) {
			throw new AppBizException(2, "缴费金额");
		}

		Map<String, Object> paMap = new HashMap<String, Object>();
		paMap.put("commID", propFeePaybill.getCommID());
		paMap.put("feeTypeID", propFeePaybill.getFeeTypeID());
		paMap.put("apartmentID", propFeePaybill.getApartmentID());
		paMap.put("belongType", "2");

		List<Map<String, Object>> ruleResult = this.getSqlSession().selectList(
				"PropFeeComputeRuleSearchMapper.getRuleByApartMentID", paMap);
		if (ruleResult == null || ruleResult.size() <= 0) {
			throw new AppBizException(2, "亲，该房屋不能存在相关的缴费信息");
		}
		BigDecimal propfee = new BigDecimal(0);
		List<PropFeeDetailDto> details = new ArrayList<PropFeeDetailDto>();

		List<String> feeDetailIDs = new ArrayList<>();
		if (ruleResult != null && ruleResult.size() >= 0) {
			for (Map<String, Object> rule : ruleResult) {

				rule = PropertyUtils.turnToEntity1(rule);

				/***
				 * 判断是否已经缴费
				 */
				/*
				 * List<PropFeePaybillDto> propFeePaybills = this
				 * .findPropFeePaybillByRelevantID(null, propFeePaybill
				 * .getCommID(), propFeePaybill.getApartmentID(), null, null,
				 * "3", null, null, "2", null, "1",
				 * ruleResult.get("ruleID").toString()); if (propFeePaybills !=
				 * null && propFeePaybills.size() > 0) { throw new
				 * AppBizException(2, "亲，该房屋不能存在相关的缴费信息"); }
				 */
				List<PropFeeDetailDto> detailsDetail = feeDetailService
						.findPropFeeDetailByRelevantID(null,
								propFeePaybill.getApartmentID(),
								propFeePaybill.getFeeTypeID(), null, null,
								null, "1", rule.get("ruleID").toString(), null);
				if (detailsDetail != null && detailsDetail.size() > 0) {
					for (PropFeeDetailDto propFeeDetailDto : detailsDetail) {
						if (!"1".equals(propFeeDetailDto.getStatus())) {
							propfee = propfee.add(propFeeDetailDto.getAmount());
							feeDetailIDs.add(propFeeDetailDto.getFeeDetailID());
						}
					}

				} else {

					if ("2".equals(rule.get("validityType").toString())) {

						continue;

					}

					String money = propFeeComputeRuleService.completeRule(rule
							.get("ruleID").toString(), propFeePaybill
							.getCommID(), propFeePaybill.getApartmentID());

					if (!StringUtils.isBlank(money)) {
						propFeePaybill.setRuleID(rule.get("ruleID").toString());
						propfee = propfee.add(new BigDecimal(money));

						/****
						 * 添加缴费细想
						 */
						PropFeeDetailDto propFeeDetail = new PropFeeDetailDto();

						propFeeDetail.setAmount(propFeePaybill.getPayMoney());

						propFeeDetail.setRuleID(rule.get("ruleID").toString());

						propFeeDetail.setRealamount(propFeeDetail.getAmount());
						propFeeDetail.setFeeAmount(propFeeDetail.getAmount()
								.toString());
						// propFeeDetail.setFeePrice(null);
						propFeeDetail.setApartmentID(propFeePaybill
								.getApartmentID());
						propFeeDetail.setFeeTypeID(propFeePaybill
								.getFeeTypeID());
						propFeeDetail.setType("1");
						propFeeDetail.setStatus("1");
						propFeeDetail.setFeeDate(DateUtil.getCurrentDate(
								new Date(), "yyyy-MM"));
						propFeeDetail.setFeeDetailID(IdUtil.getuuId());
						propFeeDetail.setItemStat(TypeConst.FLAG_ON);
						propFeeDetail.setTscreate(new Date());
						propFeeDetail.setTsedit(new Date());
						propFeeDetail.setPaytime(new Date());
						propFeeDetail.setIspre("1");
						feeDetailIDs.add(propFeeDetail.getFeeDetailID());

						details.add(propFeeDetail);
					}

				}

			}

			/***
			 * 添加西厢
			 */
			if (propfee.compareTo(propFeePaybill.getPayMoney()) != 0) {
				throw new AppBizException(2, "亲，该房屋缴费金额已发生变化");
			}

			if (details != null && details.size() > 0) {
				this.getSqlSession().insert(
						"PropFeeDetailBauthMapper.bauthInsert", details);
			}

			propFeePaybill.setPayMoney(propfee);
			propFeePaybill.setPaybillID(IdUtil.getuuId());
			/**
			 * 更新缴费项目细项转态为已缴
			 * 
			 */
			feeDetailService.setFeeDetailsPay(propFeePaybill.getApartmentID(),
					feeDetailIDs,propFeePaybill.getPayTime());
			/**
			 * 添加账单细项
			 * 
			 * */

			Map<String, Object> zdxxmap = new HashMap<String, Object>();
			zdxxmap.put("feeDetailIDlist", feeDetailIDs);
			zdxxmap.put("paybill_id", propFeePaybill.getPaybillID());
			this.getSqlSession().insert(
					"CollectionItemMapper.insertpropfeepaydetail", zdxxmap);
			/**
			 * 添加缴费账单
			 */
			// propFeePaybill.setRuleID(ruleResult.get("ruleID").toString());

			propFeePaybill.setRealMoney(propFeePaybill.getPayMoney());
			propFeePaybill.setRealPay(propFeePaybill.getPayMoney());
			propFeePaybill.setSubMoney(new BigDecimal(0));
			propFeePaybill.setBillType("1");
			propFeePaybill.setPayTime(new Date());
			propFeePaybill.setStatus("2");
			propFeePaybill.setType("1");

			propFeePaybill.setItemStat(TypeConst.FLAG_ON);
			propFeePaybill.setTscreate(new Date());
			propFeePaybill.setTsedit(new Date());
			return this.getSqlSession().insert(
					"PropFeePaybillDtoMapper.insertSelective", propFeePaybill);
		}
		return 1;
	}

	@Override
	public List<PropFeePaybillDto> findPropFeePaybillByRelevantID(
			String paybillID, String commID, String apartmentID,
			String payType, String payeeID, String status,
			String exceptionstatus, String contactType, String type,
			String memID, String billType, String ruleID)
			throws AppBizException {
		/************************************************
		 * 设置输入参数
		 ************************************************/
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("paybillID", paybillID);
		map.put("commID", commID);
		map.put("apartmentID", apartmentID);
		map.put("payType", payType);
		map.put("payeeID", payeeID);
		map.put("status", status);
		map.put("exceptionstatus", exceptionstatus);
		map.put("contactType", contactType);
		map.put("type", type);
		map.put("memID", memID);
		map.put("billType", billType);
		map.put("ruleID", ruleID);
		List<PropFeePaybillDto> list = this.getSqlSession().selectList("PropFeePaybillSearchMapper.findPropFeePaybillDtoByRelevantID",
				map);
		return list;
	}

	@Override
	public int deletePayBillItem(String payBillID,UserBean userbean) throws AppBizException {
		
		
		
	List<PropFeePaybillItemDto>items=	propFeePaybillItemService.findPropFeePaybillItemByRelevantID(null, payBillID,null, null, null);
	 PropFeeAccountDto propFeeAccount=null;

	
	
	
	

	
	for (PropFeePaybillItemDto propFeePaybillItemDto : items) {
		
	if(2==propFeePaybillItemDto.getItemType()){
			
			if(propFeeAccount==null){
				propFeeAccount=propFeeAccountService.findPropFeeAccountByID(propFeePaybillItemDto.getLinkID());
			}
			
			AmountHandleDto amountHandle=new AmountHandleDto();
			amountHandle.setOperation("1");
			amountHandle.setAccountID(propFeePaybillItemDto.getLinkID());
			amountHandle.setMoney(propFeePaybillItemDto.getMoney());
			amountHandle.setLogType(7);
			amountHandle.setLinkID(propFeePaybillItemDto.getPaybillID());
			amountHandle.setCreateuser(userbean.getUserName());
			amountHandle.setCreateuserID(userbean.getUserID());
//			amountHandle.setApartmentID(paybill.getApartmentID());
			amountHandle.setRemark("删除账单归还余额支付的 "+propFeePaybillItemDto.getMoney()+"元");
			amountHandle.setTotalMoney(propFeeAccount.getMoney());
			propFeeAccountService.handleAccount(amountHandle);	
			propFeeAccount.setMoney(propFeeAccount.getMoney().add(propFeePaybillItemDto.getMoney()));
			
		}
		if(3==propFeePaybillItemDto.getItemType()){
			
			if(propFeeAccount==null){
				propFeeAccount=propFeeAccountService.findPropFeeAccountByID(propFeePaybillItemDto.getLinkID());
			}
			
			AmountHandleDto amountHandle=new AmountHandleDto();
			amountHandle.setOperation("2");
			amountHandle.setCreateuser(userbean.getUserName());
			amountHandle.setCreateuserID(userbean.getUserID());
			amountHandle.setAccountID(propFeePaybillItemDto.getLinkID());
			amountHandle.setMoney(propFeePaybillItemDto.getMoney());
			amountHandle.setLogType(7);
			amountHandle.setLinkID(propFeePaybillItemDto.getPaybillID());
//			amountHandle.setApartmentID(paybill.getApartmentID());
			amountHandle.setRemark("删除账单撤销还款 "+propFeePaybillItemDto.getMoney()+"元");
			amountHandle.setTotalMoney(propFeeAccount.getMoney());
			propFeeAccountService.handleAccount(amountHandle);	
			propFeeAccount.setMoney(propFeeAccount.getMoney().subtract(propFeePaybillItemDto.getMoney()));
			
		}
        if(4==propFeePaybillItemDto.getItemType()){
        	if(propFeeAccount==null){
				propFeeAccount=propFeeAccountService.findPropFeeAccountByID(propFeePaybillItemDto.getLinkID());
			}
        	AmountHandleDto amountHandle=new AmountHandleDto();
			amountHandle.setOperation("1");
			amountHandle.setCreateuser(userbean.getUserName());
			amountHandle.setCreateuserID(userbean.getUserID());
			amountHandle.setAccountID(propFeePaybillItemDto.getLinkID());
			amountHandle.setMoney(propFeePaybillItemDto.getMoney());
			amountHandle.setLogType(7);
			amountHandle.setLinkID(propFeePaybillItemDto.getPaybillID());
//			amountHandle.setApartmentID(paybill.getApartmentID());
			amountHandle.setRemark("删除账单撤销借款 "+propFeePaybillItemDto.getMoney()+"元");
			amountHandle.setTotalMoney(propFeeAccount.getMoney());
			propFeeAccountService.handleAccount(amountHandle);	
			propFeeAccount.setMoney(propFeeAccount.getMoney().add(propFeePaybillItemDto.getMoney()));
				
		}
       if(5==propFeePaybillItemDto.getItemType()){
    		if(propFeeAccount==null){
				propFeeAccount=propFeeAccountService.findPropFeeAccountByID(propFeePaybillItemDto.getLinkID());
			}
    	  	AmountHandleDto amountHandle=new AmountHandleDto();
    				amountHandle.setOperation("2");
    				amountHandle.setCreateuser(userbean.getUserName());
    				amountHandle.setCreateuserID(userbean.getUserID());
    				amountHandle.setAccountID(propFeePaybillItemDto.getLinkID());
    				amountHandle.setMoney(propFeePaybillItemDto.getMoney());
    				amountHandle.setLogType(7);
    				amountHandle.setLinkID(propFeePaybillItemDto.getPaybillID());
//    				amountHandle.setApartmentID(paybill.getApartmentID());
    				amountHandle.setRemark("删除账单撤销充值"+propFeePaybillItemDto.getMoney()+"元");
    				amountHandle.setTotalMoney(propFeeAccount.getMoney());
    				propFeeAccountService.handleAccount(amountHandle);	
    				propFeeAccount.setMoney(propFeeAccount.getMoney().subtract(propFeePaybillItemDto.getMoney()));
    				
        }
		
	}
	
	// TODO Auto-generated method stub
		return 0;
	}
//线上缴费校验，不支持减免金额和
	@Override
	public Map<String,Object> _check(
			PayBillDto payBillDto) throws Exception {
		BigDecimal subMoney=new BigDecimal(StringUtils.toString(payBillDto.getSubMoney(), "0"));
		BigDecimal oweMoney=new BigDecimal(StringUtils.toString(payBillDto.getOweMoney(), "0"));
	

		//判断房屋账户金额
		if(subMoney.compareTo(BigDecimal.ZERO)>0||oweMoney.compareTo(BigDecimal.ZERO)>0){
			
			if(subMoney.compareTo(BigDecimal.ZERO)>0&&oweMoney.compareTo(BigDecimal.ZERO)>0)
			{
				
				throw new AppBizException(2, "提交信息异常");	
			}
		
			PropFeeAccountDto	propFeeAccount=	this.getAmount(payBillDto.getApartmentID());
			if(propFeeAccount==null){
				
				throw new AppBizException(2, "无账户信息");	
				
			}
			if(subMoney.compareTo(BigDecimal.ZERO)>0&&subMoney.compareTo(propFeeAccount.getMoney())>0){
				
				throw new AppBizException(2, "账户信息余额不足");	
				
				
			}
            if(oweMoney.compareTo(BigDecimal.ZERO)>0&&oweMoney.compareTo(propFeeAccount.getMoney())!=0){
				
				throw new AppBizException(2, "欠费信息不符");	
				
				
			}
			
		}
		//判断是否有预缴账单 
		if(payBillDto.getPreFeeList()!=null&&payBillDto.getPreFeeList().size()!=0){
			
			List<String> ids=computeBillService.crePreFeeDetail(payBillDto.getCommID(), payBillDto.getApartmentID(), payBillDto.getPreFeeList());
			
			payBillDto.getFeeDetailIDs().addAll(ids);
		}
		
		
		
		
		//判断是否已缴
	Map<String,Object> res=	feeDetailService._check(payBillDto.getApartmentID(), payBillDto.getFeeDetailIDs());
		
		// TODO Auto-generated method stub
		return res;
	}

	@Override
	public Paybill getPayBillDetailByOrderID(String orderID)
			throws AppBizException {

		// TODO Auto-generated method stub
				return this.getSqlSession().selectOne(
						"PropFeePaybillMapper.selectByOrderID", orderID);
	
	}
}
